package poweroutage;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Solution {
	private static class Edge implements Comparable<Edge> {
		int i, j, c;
		public Edge(int i, int j, int c) {
			this.i = i;
			this.j = j;
			this.c = c;
		}
		@Override
		public int compareTo(Edge e) {
			return c - e.c;
		}
	}
	private static class Cluster extends ArrayList<Edge> implements Comparable<Cluster> {
		private static final long serialVersionUID = 1L;
		@Override
		public boolean equals(Object obj) {
			if(obj instanceof Cluster)
				return this == ((Cluster)obj);
			return false;
		}
		@Override
		public int compareTo(Cluster c) {
			if(size() <= 0)
				return 1;
			if(c.size() <= 0)
				return -1;
			return get(0).c - c.get(0).c;
		}
	}
	private static int root(int ind, int[] p) {
		int root = ind;
		while(p[root] >= 0)
			root = p[root];
		if(ind != root)
			p[ind] = root;
		return root;
	}
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		try {
			int T = in.nextInt();
			for(int t = 0; t < T; t++) {
				int n = in.nextInt(), m = in.nextInt(), k = in.nextInt();
				List<Cluster> clust = new ArrayList<Cluster>(); // list of clusters
				Cluster nodeClust[] = new Cluster[n]; // cluster to which each node belongs
				for(int c = 0; c < n; c++) {
					// add each node to its own cluster
					Cluster newClust = new Cluster();
					clust.add(newClust);
					nodeClust[c] = newClust;
				}
				for(int m1 = 0; m1 < m; m1++) {
					int i = in.nextInt() - 1, j = in.nextInt() - 1;
					Edge e = new Edge(i, j, in.nextInt());
					if(nodeClust[i] != nodeClust[j]) {
						// merge clusters i and j
						nodeClust[i].addAll(nodeClust[j]);
						Cluster delClust = nodeClust[j];
						for(Edge ej : delClust) {
							nodeClust[ej.i] = nodeClust[i];
							nodeClust[ej.j] = nodeClust[i];
						}
						nodeClust[j] = nodeClust[i];
						clust.remove(delClust);
					}
					// add edge to the merged cluster
					nodeClust[i].add(e);
				}
				// we should have generators at least as many as the number of clusters
				if(k < clust.size()) {
					System.out.println("Impossible!");
					continue;
				}
				int elems = 0;
				for(int c = 0; c < clust.size(); c++) {
					// find minimum spanning tree for each cluster
					// here we use kruskal's algorithm
					Cluster clustc = clust.get(c);
					Collections.sort(clustc);
					int p[] = new int[n];
					for(int i = 0; i < n; i++)
						p[i] = -1;
					for(int ind = 0; ind < clustc.size(); ind++) {
						Edge e = clustc.get(ind);
						// find root of node i
						int ri = root(e.i, p);
						// find root of node j
						int rj = root(e.j, p);
						if(ri != rj) {
							p[rj] = ri;
							elems++;
						} else
							clustc.remove(ind--);
					}
				}
				// sort merged cluster
				Collections.sort(clust);
				// allocate one generator to each cluster
				// for each another generator we can get rid of one edge
				// add costs of top mergedClust.size() - (k - clust.size()) edges in the merged cluster
				int end = elems - k + clust.size();
				long cost = 0;
				for(int ind = 0; ind < end; ind++) {
					Cluster c = clust.remove(0);
					cost += c.remove(0).c;
					int p = 0;
					while(p < clust.size() && clust.get(p).compareTo(c) < 0)
						p++;
					clust.add(p, c);
				}
				System.out.println(cost);
			}
		} finally {
			in.close();
		}
	}
}
